package com.sunyur.tailor.channel.service.inner.supplier.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.sunyur.tailor.channel.common.inner.base.SunyurListResult;
import com.sunyur.tailor.channel.common.inner.base.SunyurResult;
import com.sunyur.tailor.channel.common.inner.util.SunyurClientUtil;
import com.sunyur.tailor.channel.common.inner.util.SunyurResultUtil;
import com.sunyur.tailor.channel.common.middle.base.ChannelListResult;
import com.sunyur.tailor.channel.common.middle.base.ChannelResult;
import com.sunyur.tailor.channel.common.middle.enums.MiddleResultEnum;
import com.sunyur.tailor.channel.common.middle.util.ChannelListResultUtil;
import com.sunyur.tailor.channel.common.middle.util.ChannelResultUtil;
import com.sunyur.tailor.channel.service.inner.supplier.model.*;
import com.sunyur.tailor.channel.service.inner.supplier.param.*;
import com.sunyur.tailor.channel.service.inner.supplier.service.SunyurSupplierService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @ClassName SunyurSupplierServiceImpl
 * @Description 供应商相关接口实现
 * @Author xuhui
 * @Date 2021/5/11 14:29
 * @Version 1.0
 */
@Service("sunyurSupplierService")
public class SunyurSupplierServiceImpl implements SunyurSupplierService {

    private static final Logger LOGGER_INFO = LoggerFactory.getLogger(SunyurSupplierServiceImpl.class);
    private static final Logger LOGGER_ERROR = LoggerFactory.getLogger(SunyurSupplierServiceImpl.class);

    /**
     * 请求商越Client
     */
    @Autowired
    private SunyurClientUtil sunyurClient;

    /**
     * 供应商信息同步 链接
     */
    @Value("${sunyur.api.syncSupplierList}")
    private String syncSupplierList;

    /**
     * 供应商银行信息同步 链接
     */
    @Value("${sunyur.api.syncSupplierBankList}")
    private String syncSupplierBankList;

    /**
     * 供应商银行联系人同步 链接
     */
    @Value("${sunyur.api.syncSupplierUserList}")
    private String syncSupplierUserList;

    /**
     * 获取供应商信息 链接
     */
    @Value("${sunyur.api.getSupplierInfo}")
    private String getSupplierInfo;

    /**
     * 获取供应商信息通过供应商编码 链接
     */
    @Value("${sunyur.api.getSupplierByCode}")
    private String getSupplierByCode;

    /**
     * 获取供应商银行信息 链接
     */
    @Value("${sunyur.api.getSupplierBank}")
    private String getSupplierBank;

    /**
     * 获取供应商联系人信息 链接
     */
    @Value("${sunyur.api.getSupplierUser}")
    private String getSupplierUser;
    /**
     * 获取供应商联系人信息 链接
     */
    @Value("${sunyur.api.getSupplierAuth}")
    private String getSupplierAuth;
    /**
     * 获取供应商变更信息 链接
     */
    @Value("${sunyur.api.getSupplierInfoChange}")
    private String getSupplierInfoChange;
    /**
     * 获取供应商状态变更信息 链接
     */
    @Value("${sunyur.api.getSupplierStatusChange}")
    private String getSupplierStatusChange;

    /**
     * 根据条件查询供应商 链接
     */
    @Value("${sunyur.api.qeurySupplier}")
    private String qeurySupplier;

    /**
     * 根据供应商CODE获取 供应商供货关系中下的供货品类
     */
    @Value("${sunyur.api.getRelBySupplierCode}")
    private String getRelBySupplierCode;

    /**
     * 获取供货品类基础数据
     */
    @Value("${sunyur.api.getRelBySupplyCategory}")
    private String getRelBySupplyCategory;


    @Override
    public ChannelResult syncSupplierList(List<SupplierParam> supplierParamList) throws Exception {
        LOGGER_INFO.info("SunyurSupplierServiceImpl syncSupplierList supplierParamList.size is {}， param is {}", supplierParamList.size(), JSON.toJSONString(supplierParamList));
        if (CollectionUtils.isEmpty(supplierParamList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), "SunyurSupplierServiceImpl syncSupplierList supplierParamList is null");
        }
        // 参数按长度分割
        List<List<SupplierParam>> supplierList = Lists.partition(supplierParamList, 10);
        // 返回错误信息结果集
        List<String> errorMsgList = Lists.newArrayList();
        // 循环调用创建或更新供应商接口
        for (int i = 0; i < supplierList.size(); i++) {
            // 调用主线创建或更新供应商接口
            SunyurResult sunyurResult = sunyurClient.execPost(syncSupplierList, JSON.toJSONString(supplierList.get(i)), null);
            // 某次调用主线返回错误（本次新增失败，记录错误信息，继续新增下一批）
            if (!SunyurResultUtil.isSuccess(sunyurResult)) {
                LOGGER_ERROR.error("第{}批失败， syncSupplierList loop call sunyur request fail, param is {}, result is {}", i, JSON.toJSONString(supplierList.get(i)), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add("第" + i + "批失败，" + sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelListResultUtil.success(null);
    }

    @Override
    public ChannelResult syncSupplierBnakList(List<SupplierBankParam> supplierBankParamList) throws Exception {
        LOGGER_INFO.info("SunyurSupplierServiceImpl syncSupplierBankList supplierBankParamList.size is {}， param is {}", supplierBankParamList.size(), JSON.toJSONString(supplierBankParamList));
        if (CollectionUtils.isEmpty(supplierBankParamList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), "SunyurSupplierServiceImpl syncSupplierBankList supplierBankParamList is null");
        }
        // 参数按长度分割
        List<List<SupplierBankParam>> supplierBankList = Lists.partition(supplierBankParamList, 10);
        // 返回错误信息结果集
        List<String> errorMsgList = Lists.newArrayList();
        // 循环调用创建或更新供应商接口
        for (int i = 0; i < supplierBankList.size(); i++) {
            // 调用主线创建或更新供应商接口
            SunyurResult sunyurResult = sunyurClient.execPost(syncSupplierBankList, JSON.toJSONString(supplierBankList.get(i)), null);
            // 某次调用主线返回错误（本次新增失败，记录错误信息，继续新增下一批）
            if (!SunyurResultUtil.isSuccess(sunyurResult)) {
                LOGGER_ERROR.error("第{}批失败， syncSupplierBnakList loop call sunyur request fail, param is {}, result is {}", i, JSON.toJSONString(supplierBankList.get(i)), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add("第" + i + "批失败，" + sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelListResultUtil.success(null);
    }

    @Override
    public ChannelResult syncSupplierUserList(List<SupplierUserParam> supplierUserParamList) throws Exception {
        LOGGER_INFO.info("SunyurSupplierServiceImpl syncSupplierUserList supplierUserParamList.size is {}， param is {}", supplierUserParamList.size(), JSON.toJSONString(supplierUserParamList));
        if (CollectionUtils.isEmpty(supplierUserParamList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), "SunyurSupplierServiceImpl syncSupplierUserList supplierUserParamList is null");
        }

        // 参数按长度分割
        List<List<SupplierUserParam>> supplierUserList = Lists.partition(supplierUserParamList, 10);
        // 返回错误信息结果集
        List<String> errorMsgList = Lists.newArrayList();
        // 循环调用创建或更新供应商接口
        for (int i = 0; i < supplierUserList.size(); i++) {
            // 调用主线创建或更新供应商接口
            SunyurResult sunyurResult = sunyurClient.execPost(syncSupplierUserList, JSON.toJSONString(supplierUserList.get(i)), null);
            // 某次调用主线返回错误（本次新增失败，记录错误信息，继续新增下一批）
            if (!SunyurResultUtil.isSuccess(sunyurResult)) {
                LOGGER_ERROR.error("第{}批失败， syncSupplierUserList loop call sunyur request fail, param is {}, result is {}", i, JSON.toJSONString(supplierUserList.get(i)), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add("第" + i + "批失败，" + sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelListResultUtil.success(null);
    }

    @Override
    public ChannelResult<SupplierModel> getSupplierByCreditCode(SupplierByCodeParam supplierByCodeParam) {
        if (ObjectUtils.isEmpty(supplierByCodeParam) || StringUtils.isBlank(supplierByCodeParam.getCreditCode())) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        String newUrl = getSupplierInfo + "?creditCode=" + supplierByCodeParam.getCreditCode() + "&creditCodeType=CREDIT_CODE" + supplierByCodeParam.getCreditCodeType();
        SunyurResult<SupplierModel> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<SupplierModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.success(sunyurResult.getContent());
        }
        return ChannelResultUtil.error(sunyurResult.getCode(), sunyurResult.getErrorMessage());
    }

    @Override
    public ChannelListResult<SupplierBankModel> getSupplierBankByCreditCode(SupplierBankByCodeParam supplierBankByCodeParam) {
        if (ObjectUtils.isEmpty(supplierBankByCodeParam) || StringUtils.isBlank(supplierBankByCodeParam.getCreditCode())) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        // 调用主线获取供应商银行账号信息接口
        TypeReference<SunyurListResult<SupplierBankModel>> typeReference = new TypeReference<SunyurListResult<SupplierBankModel>>() {
        };
        SunyurListResult<SupplierBankModel> sunyurListResult = sunyurClient.execListPost(getSupplierBank, JSON.toJSONString(supplierBankByCodeParam), typeReference);
        // 主线返回错误
        if (!SunyurResultUtil.isSuccess(sunyurListResult)) {
            return ChannelListResultUtil.error(sunyurListResult.getCode(), sunyurListResult.getErrorMessage());
        }
        // 判断是否存在下一页
        if (!SunyurResultUtil.isNextPage(sunyurListResult)) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }
        // 返回结果集
        List<SupplierBankModel> supplierBankModelList = Lists.newArrayList();
        // 将第一次查询的结果收集
        supplierBankModelList.addAll(sunyurListResult.getContent());
        // 循环查询剩余数据
        for (int i = supplierBankByCodeParam.getPage() + 1; i <= sunyurListResult.getTotalPage(); i++) {
            supplierBankByCodeParam.setPage(i);
            // 调用主线获取供应商银行账号信息接口
            SunyurListResult<SupplierBankModel> sunyurPageResult = sunyurClient.execListPost(getSupplierBank, JSON.toJSONString(supplierBankByCodeParam), typeReference);
            // 某次调用主线返回错误
            if (!SunyurResultUtil.isSuccess(sunyurPageResult)) {
                LOGGER_ERROR.error("getSupplierBankByCreditCode loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(supplierBankByCodeParam), JSON.toJSONString(sunyurPageResult));
                return ChannelListResultUtil.error(sunyurPageResult.getCode(), sunyurPageResult.getErrorMessage());
            }
            supplierBankModelList.addAll(sunyurPageResult.getContent());
        }
        return ChannelListResultUtil.success(supplierBankModelList);
    }

    @Override
    public ChannelResult<List<SupplierUserModel>> getSupplierUserByCreditCode(String creditCode) throws Exception {
        LOGGER_INFO.info("SunyurSupplierServiceImpl getSupplierUserByCreditCode param is {}", JSON.toJSONString(creditCode));
        if (StringUtils.isBlank(creditCode)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurSupplierServiceImpl getSupplierUserByCreditCode param is null");
        }
        String newUrl = getSupplierUser + "?creditCode=" + creditCode;
        // 调用主线获取供应商接口
        SunyurResult<List<SupplierUserModel>> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<List<SupplierUserModel>>>() {
        });
        // 存在错误信息
        if (!SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurResult.getErrorMessage());
        }
        return ChannelListResultUtil.success(sunyurResult.getContent());
    }

    @Override
    public ChannelResult<SupplierModel> getByCode(String code) throws Exception {
        if (StrUtil.isBlank(code)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        String newUrl = getSupplierByCode + "?code=" + code;
        SunyurResult<SupplierModel> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<SupplierModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.success(sunyurResult.getContent());
        }
        return ChannelResultUtil.error(sunyurResult.getCode(), sunyurResult.getErrorMessage());
    }

    @Override
    public ChannelResult<SupplierAuthModel> getSupplierAuth(String purCode) throws Exception {
        if (StrUtil.isBlank(purCode)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        String newUrl = getSupplierAuth + "?purCode=" + purCode;
        SunyurResult<SupplierAuthModel> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<SupplierAuthModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.success(sunyurResult.getContent());
        }
        return ChannelResultUtil.error(sunyurResult.getCode(), sunyurResult.getErrorMessage());
    }

    @Override
    public ChannelResult<SupplierInfoChangeModel> getSupplierInfoChange(String purCode) throws Exception {
        if (StrUtil.isBlank(purCode)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        String newUrl = getSupplierInfoChange + "?purCode=" + purCode;
        SunyurResult<SupplierInfoChangeModel> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<SupplierInfoChangeModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.success(sunyurResult.getContent());
        }
        return ChannelResultUtil.error(sunyurResult.getCode(), sunyurResult.getErrorMessage());
    }

    @Override
    public ChannelResult<SupplierStatusChangeModel> getStatusChange(String purCode) throws Exception {
        if (StrUtil.isBlank(purCode)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        String newUrl = getSupplierStatusChange + "?purCode=" + purCode;
        SunyurResult<SupplierStatusChangeModel> sunyurResult = sunyurClient.execGet(newUrl, null, new TypeReference<SunyurResult<SupplierStatusChangeModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurResult)) {
            return ChannelResultUtil.success(sunyurResult.getContent());
        }
        return ChannelResultUtil.error(sunyurResult.getCode(), sunyurResult.getErrorMessage());
    }

    @Override
    public ChannelListResult<SupplierModel> querySupplier(SupplierQueryParam supplierQueryParam) throws Exception {
        if (ObjectUtils.isEmpty(supplierQueryParam)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        SunyurListResult<SupplierModel> sunyurListResult = sunyurClient.execListPost(qeurySupplier, JSON.toJSONString(supplierQueryParam), new TypeReference<SunyurListResult<SupplierModel>>() {
        });
        if (SunyurResultUtil.isSuccess(sunyurListResult)) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }
        return ChannelListResultUtil.error(sunyurListResult.getCode(), sunyurListResult.getErrorMessage());
    }

    @Override
    public ChannelListResult<SupplyCategoryModel> getRelBySupplierCode(SupplierByCodeParam param) throws Exception {
        if (ObjectUtils.isEmpty(param)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        SunyurListResult<SupplyCategoryModel> sunyurListResult = sunyurClient.execListPost(getRelBySupplierCode, JSON.toJSONString(param), new TypeReference<SunyurListResult<SupplyCategoryModel>>() {
        });
        if ("success".equals(sunyurListResult.getCode()) || "00000".equals(sunyurListResult.getCode())) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }
        return ChannelListResultUtil.error(sunyurListResult.getCode(), sunyurListResult.getErrorMessage());
    }

    @Override
    public ChannelListResult<SupplyCategoryModel> getRelBySupplyCategoryCode(SupplyCategoryParam param) throws Exception {

        if (ObjectUtils.isEmpty(param)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), MiddleResultEnum.PARAM_NULL.getValue());
        }
        SunyurListResult<SupplyCategoryModel> sunyurListResult = sunyurClient.execListPost(getRelBySupplyCategory, JSON.toJSONString(param), new TypeReference<SunyurListResult<SupplyCategoryModel>>() {
        });
        if ("success".equals(sunyurListResult.getCode()) || "00000".equals(sunyurListResult.getCode())) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }
        return ChannelListResultUtil.error(sunyurListResult.getCode(), sunyurListResult.getErrorMessage());
    }
}
